/**
 * Created by Administrator on 2017/1/15.
 */

var pomelo = require('pomelo');
var config = require('./config');

var MJ = require('../MJ/MJ');
var MJRoom = require('../MJ/room').MJRoom;

var JiCard = require('./jiCard').JiCard;
var Const = require('./const');
var SubCode = require('../subCode');

exports.QRMJRoom = MJRoom.extend({

    _defaultJiCards: {},     // 默认鸡牌
    _huNextCard: 0,           // 胡牌的下一张牌
    _huJiCards: [],           // 胡牌翻出的鸡牌
    _jiCards: {},             // 鸡牌 {$card: JiCard}

    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);

        this._defaultJiCards = {};
        this._huNextCard = 0;
        this._huJiCards = [];
        this._jiCards = {};
    },

    checkInit: function() {
        if (!this._super()) {
            return false;
        }

        this._defaultJiCards[MJ.getValue(MJ.Color.TIAO, 1)] = 1;
        if (this.getOption('WGJ')) {
            this._defaultJiCards[MJ.getValue(MJ.Color.TONG, 8)] = 2;
        }

        return true;
    },

    isDefaultJiCard: function(card) {
        return this._defaultJiCards.hasOwnProperty(card);
    },

    getJiCards: function() {
        return this._jiCards;
    },

    getJiCard: function(card) {
        return this._jiCards[card];
    },

    addJiCard: function(card, from) {
        var jiCard = new JiCard(card, from);
        if (this.isDefaultJiCard(card)) {
            jiCard.setBaseScore(this._defaultJiCards[card]);
        }
        this._jiCards[card] = jiCard;
        return jiCard;
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoomConfig: function() {
        var cfg = this._super();
        cfg.waitTimeoutTime = 180;
        cfg.waitTimeoutAfter = 10;
        return cfg;
    },

    getReconnectInfo: function(rePlayer) {
        var info = this._super(rePlayer);
        info.jiCards = this.getJiCards();
        return info;
    },

    onBeforeStartNewRound: function() {
        this._super();
        this._huNextCard = 0;
        this._huJiCards = [];
        this._jiCards = {};
    },

    onAfterStartNewRound: function() {
        this._super();
        this.initPlayersHandCards();

        if (!this.isSelectColor()) {
            this.startPlay();
        } else {
            var now = this.getNowTime();
            this.enumPlaying(function(eIndex, ePlayer) {
                ePlayer.setWaitHandleTime(now);
            });
        }
    },

    startPlay: function() {
        var dealer = this.getDealerIndex();

        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != dealer) {
                var tings = ePlayer.checkTing();
                if (tings.length > 0) {
                    this._hangupTask.addTingTask(eIndex, tings);
                }
            }
        }.bind(this));

        this._sendHangupTask(this._startPlay);
    },

    _startPlay: function() {
        this._changeCurPlay(this.getDealerIndex());
        this._doCheckNewCardHangupTask();
    },

    onBeforePlayCard: function(player, msg, card) {
        var code = this._super(player, msg, card);
        if (code) {
            return code;
        }

        if (player.isBaoTing() && card != player.getLastCard()) { //天听不能换牌
            return SubCode.MJ_IS_BAOTING;
        }
    },

    onAfterPlayCard: function(player, card, playInfo) {
        this._super(player, card, playInfo);

        var isFirstJi = false;

        // 判断冲锋鸡
        if (this.isDefaultJiCard(card)) {
            var jiCard = this.getJiCard(card);
            if (!jiCard) {
                this.addJiCard(card, player.getIndex());
                isFirstJi = true;
            } else {
                jiCard.addNum();
            }
        }

        playInfo.isFirstJi = isFirstJi;
    },

    onAfterPengTask: function(player, card, pengTask) {
        // 判断责任鸡
        if (this.isDefaultJiCard(card)) {
            var jiCard = this.getJiCard(card);
            if (jiCard && (jiCard.getNum() == 1)) {
                jiCard.setOwner(player.getIndex());
                this.broadcast("onPlayerZRJ", {
                    playerIndex: player.getIndex(),
                    card: card,
                    from: jiCard.getFrom()
                });
            }
        }
    },

    onAfterGangTask: function(player, card, gangTask, gangInfo) {
        this._super(player, card, gangTask, gangInfo);

        // 判断责任鸡
        if (this.isDefaultJiCard(card)) {
            var jiCard = this.getJiCard(card);
            if (jiCard && (gangTask.gang == MJ.Gang.DIAN)) {
                jiCard.setOwner(player.getIndex());
                this.broadcast("onPlayerZRJ", {
                    playerIndex: player.getIndex(),
                    card: card,
                    from: jiCard.getFrom()
                });
            }
        }
    },

    checkNewCardHangupTask: function() {
        var player = this.getPlayerByIndex(this._curPlay);

        var huPattern = player.checkHu();
        if (huPattern != MJ.Pattern.NONE) {
            var rules = [];
            if (player.isFirstHand()) {
                if (player.getIndex() == this.getDealerIndex()) {
                    rules.push(Const.ScoreRule.TH);
                }
            } else {
                if (player.isBaoTing()) {
                    rules.push(Const.ScoreRule.BT);
                }
            }
            if (this.getCurGang()) {
                rules.push(Const.ScoreRule.GSH);
            }

            // 自摸不需要豆
            var card = player.getLastCard() || player.getInitLastCard();
            this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
        }

        if (!player.isBaoTing()) {
            var gangArray = player.checkGang();
            if (gangArray.length > 0) {
                this._hangupTask.addGangTask(player.getIndex(), gangArray[0]);
            }
        }
    },

    checkPlayCardHangupTask: function( card) {
        var player = this.getCurPlayer();
        if (!player.isBaoTing() && player.getPlayHand() == 1) {
            var tings = player.checkTing();
            if (tings.length > 0) {
                this._hangupTask.addTingTask(player.getIndex(), tings);
            }
            this._sendHangupTask(this._checkPlayCardHangupTask, [card]);
        } else {
            this._checkPlayCardHangupTask(card);
        }
    },

    _checkPlayCardHangupTask: function( card) {
        var curPlay = this.getCurPlay();
        var curPlayer = this.getCurPlayer();
        var enableDianGangHu = this.getHideOption("dianGangHu");

        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != curPlay) {
                if (!ePlayer.isPassHu()) {
                    var huPattern = ePlayer.checkHuWithCard(card);
                    if (huPattern != MJ.Pattern.NONE) {
                        var rules = [];
                        if (ePlayer.isFirstHand()) {
                            if (ePlayer.getIndex() != this.getDealerIndex()) {
                                rules.push(Const.ScoreRule.DIHU);
                            }
                        } else {
                            if (ePlayer.isBaoTing()) {
                                rules.push(Const.ScoreRule.BT);
                            }
                        }
                        if (this.getCurGang() > 0) {
                            var lastGang = curPlayer.getLastGang();
                            if (lastGang && (lastGang.gang != MJ.Gang.DIAN || this.getHideOption("dianGangGSP"))) {
                                rules.push(Const.ScoreRule.GSP);
                            }
                        }

                        var enableHu = false;
                        if (huPattern != MJ.Pattern.NORMAL || rules.length > 0 || curPlayer.isBaoTing()) {
                            enableHu = true;
                        } else {
                            var gangCards = ePlayer.getGangCards();
                            if (gangCards.length < 1) {
                                enableHu = false;
                            } else {
                                if (enableDianGangHu) {
                                    enableHu = true;
                                } else {
                                    gangCards.forEach(function(gangInfo) {
                                        if (gangInfo.gang != MJ.Gang.DIAN) {
                                            enableHu = true;
                                        }
                                    });
                                }
                            }
                        }

                        if (enableHu) {
                            this._hangupTask.addHuTask(ePlayer.getIndex(), card, curPlay, huPattern, rules);
                        }
                    }
                }

                if (!ePlayer.isBaoTing()) {
                    if (ePlayer.checkPengWithCard(card)) {
                        this._hangupTask.addPengTask(eIndex, card, curPlay);
                    }
                    if (ePlayer.checkGangWithCard(card)) {
                        this._hangupTask.addGangTask(eIndex, card, curPlay, MJ.Gang.DIAN);
                    }
                }
            }
        }.bind(this));
    },

    checkGangHangupTask: function(playerIndex, gangInfo) {
        var card = gangInfo.card;
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != playerIndex) {
                var huPattern = ePlayer.checkHuWithCard(card);
                if (huPattern != MJ.Pattern.NONE) { // 抢杠
                    var rules = [];
                    rules.push(Const.ScoreRule.QG);

                    if (ePlayer.isBaoTing()) {
                        rules.push(Const.ScoreRule.BT);
                    }

                    this._hangupTask.addHuTask(eIndex, card, playerIndex, huPattern, rules);
                }
            }
        }.bind(this));
    },

    checkGangTaskQG: function(task, gangInfo) {
        return gangInfo.gang == MJ.Gang.BA;
    },

    checkHuSettlement: function() {
        return true;
    },

    onSettlementHuTask: function(task) {
        var playerIndex = task.playerIndex;
        var pattern = task.pattern;
        var card = task.card;
        var from = task.from;
        var rules = task.rules;
        var huPlayer = this.getPlayerByIndex(playerIndex);

        var isZM = (playerIndex == from); // 是否是自摸

        var targetsIndex = [];
        var targets = [];
        if (isZM) {
            this.enumPlayers(function(eIndex, ePlayer) {
                if (eIndex != playerIndex && !ePlayer.isRoundHu()) {
                    targetsIndex.push(eIndex);
                    targets.push(ePlayer);
                }
            });
        } else {
            targetsIndex.push(from);
            targets.push(this.getPlayerByIndex(from));
        }

        var patternScore = Const.PatternScore[pattern];

        for (var i = 0; i < rules.length; ++i) {
            var rule = rules[i];
            switch (rule) {
                case Const.ScoreRule.GSH:
                    huPlayer.setRoundScoreRule(rule);
                    huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                    break;
                case Const.ScoreRule.GSP:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        targetPlayer.setRoundScoreRule(rule);
                        targetPlayer.setLastGangUnscored();

                        var gangInfo = targetPlayer.getLastGang();
                        if (gangInfo) {
                            huPlayer.addRoundItemScores(rule, (gangInfo.gang == MJ.Gang.DIAN) ? 3 : (this.getMaxPlayer() - 1) * 3);
                        }
                    }
                    break;
                case Const.ScoreRule.QG:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        if (targetPlayer.getIndex() == this.getCurPlay() && this.getCurGang() > 0) { // 抢杠的被抢玩家一定是当前玩家
                            targetPlayer.setRoundScoreRule(rule);
                            targetPlayer.cancelLastGangForQG(card);
                        }
                    }
                    break;
                case Const.ScoreRule.BT:
                case Const.ScoreRule.TH:
                case Const.ScoreRule.DIHU:
                    huPlayer.setRoundScoreRule(rule);
                    if (pattern == MJ.Pattern.NORMAL) {
                        patternScore = 0;
                    }
                    huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                default:
                    break;
            }
        }

        if (isZM) {
            var zms = this.getOption("ZMS") || this.getHideOption("ZMS");
            if (zms == 1) { // 自摸翻倍
                huPlayer.addRoundItemScores(Const.ScoreRule.ZM, patternScore);
            } else { // 自摸加分
                huPlayer.addRoundItemScores(Const.ScoreRule.ZM, Const.ItemScore[Const.ScoreRule.ZM]);
            }

            huPlayer.setRoundScoreRule(Const.ScoreRule.ZM);
        }

        var huResult = isZM ? MJ.Result.ZM : MJ.Result.DH;
        huPlayer.setRoundResult(huResult, targetsIndex, card);
        huPlayer.setRoundPattern(pattern, patternScore);
        targets.forEach(function(target) {
            target.setRoundResult(-huResult);
        });
    },

    onSettlement: function() {
        this._settlementHuJiCards();

        ExObject.eachKeyNum(this._defaultJiCards, function(card, value) {
            if (!this.getJiCard(card)) {
                this.addJiCard(card);
            }
        }.bind(this));

        this.enumPlayers(function(eIndex, ePlayer) {
            this._settlementPlayerTing(ePlayer);
        }.bind(this));

        if (this.isRoundHZ()) {
            this.enumPlayers(function(eIndex, ePlayer) {
                ePlayer.settlementHZScore();
            });
        } else {
            this.enumPlayers(function(eIndex, ePlayer) {
                ePlayer.settlementGangScore();
                ePlayer.settlementJiScore();
                ePlayer.settlementPatternScore();
            }.bind(this));
        }
    },

    getSettlementInfo: function() {
        var info = this._super();
        info.huNextCard = this._huNextCard;
        info.huJiCards = this._huJiCards;
        info.jiCard = this.getJiCards();
        return info;
    },

    onCurRoundFinished: function() {
        this._super();

        var oldDealerIndex = this.getDealerIndex();
        var newDealerIndex = oldDealerIndex;
        if (!this.isRoundHZ()) {
            var newDealerIndex = this.getFirstHuPlayerIndex(); //最先胡牌的为庄
            this.enumPlayers(function(eIndex, ePlayer) { // 一炮多响者为庄
                if (ePlayer.existRoundScoreRule(Const.ScoreRule.YPDX)) {
                    newDealerIndex = eIndex;
                }
            });
        } else {
            var notTingArr = [];
            this.enumPlayers(function(eIndex, ePlayer) {
                if (!ePlayer.isRoundTing()) {
                    notTingArr.push(eIndex);
                }
            });

            if (notTingArr.indexOf(oldDealerIndex) != -1) {
                newDealerIndex = this.getNextIndex(oldDealerIndex); // 庄未听牌则下家为庄
            } else if (notTingArr.length == 1 && this.getMaxPlayer() > 2) {
                newDealerIndex = notTingArr[0]; // 3人及以上的房间只有一家未听牌的为庄
            }
        }

        if (this._dealerIndex != newDealerIndex) {
            this._dealerIndex = newDealerIndex;
            this._dealerLZ = 1;
        } else {
            this._dealerLZ += 1;
        }

        this.broadcast("onDealerChanged", {
            dealer: this._dealerIndex,
            dealerLZ: this._dealerLZ
        });
    },

    /******************************************************************
     * 消息处理
     ******************************************************************/

    handleGift: function(player, msg, callback) {
        if (isNaN(msg.targetIndex)) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        var gameConfig = this.getGameConfig();
        var giftType = msg.type;

        var giftConfig = null;
        if (this.isSceneRoom()) {
            var sceneBasicConfig = this.getSceneBasicConfig();
            if (sceneBasicConfig) {
                giftConfig = sceneBasicConfig.Gift[giftType];
            }
        } else {
            giftConfig = gameConfig.Gift[giftType];
        }

        if (!giftConfig) {
            callback({code: Code.ARGS_VALUE_WRONG}); return;
        }

        var targetIndex = parseInt(msg.targetIndex);
        var targetPlayer = this.getPlayerByIndex(targetIndex);
        if (!targetPlayer) {
            callback({code: SubCode.INDEX_INVALID}); return;
        }

        if (!player.checkResource(giftConfig.costs)) {
            callback({code: Code.LACK_OF_RESOURCE}); return;
        }

        this.broadcast("onPlayerGift", {
            playerIndex: player.getIndex(),
            targetIndex: targetIndex,
            type: giftType
        });

        callback({});
        player.costResourceSync(giftConfig.costs);
    },

    handleEnjoy: function(player, msg, callback) {
        var resource = this.getGameConfig().Enjoy.costs;

        if (!player.checkResource(resource)) {
            callback({code: Code.LACK_OF_RESOURCE}); return;
        }

        callback({});
        player.costResourceSync(resource);
    },

    /******************************************************************
     * 功能接口
     ******************************************************************/

    /**
     * 结算胡牌后翻出的鸡牌
     * @private
     */
    _settlementHuJiCards: function() {
        if (this.getHuPlayerCount() == 0) {
            return;
        }

        var nextCard = this._publicCards.lookCard();
        if (!nextCard) {
            return;
        }

        this._huNextCard = nextCard;

        var color = MJ.getColor(nextCard);
        var point = MJ.getPoint(nextCard);
        var maxPoint = MJ.ColorCardNum[color].point;
        var jiCardArray = [];

        // 上鸡
        var sPoint = point + 1;
        if (sPoint > maxPoint) {
            sPoint = 1;
        }
        jiCardArray.push(MJ.getValue(color, sPoint));

        if (this.getOption("BJ")) {
            jiCardArray.push(nextCard);
        }

        if (this.getOption("SXJ")) {
            var xPoint = point - 1;
            if (xPoint < 1) {
                xPoint = 9;
            }
            jiCardArray.push(MJ.getValue(color, xPoint));
        }

        jiCardArray.forEach(function (card) {
            this._huJiCards.push(card);

            var jiCard = this.getJiCard(card);
            if (!jiCard) {
                jiCard = this.addJiCard(card);
            }

            if (this.isDefaultJiCard(card)) {
                jiCard.setKing();
            }
        }.bind(this));
    },

    /**
     * 结算玩家是否听牌
     * @param player
     * @private
     */
    _settlementPlayerTing: function(player) {
        if (player.isRoundTing()) {
            return;
        }

        // 对未胡牌的玩家检查是否听牌
        var tings = player.checkTing();
        var pattern = MJ.Pattern.NONE;
        var patternScore = 0;
        for (var i = 0; i < tings.length; ++i) {
            var ting = tings[i];
            var score = Const.PatternScore[ting.pattern];
            if (score > patternScore) {
                pattern = ting.pattern;
                patternScore = score;
            }
        }

        player.setRoundPattern(pattern, 0);
    },
});